#ifndef _DOFS_
#define _DOFS_

#include "Point.h"

/**
 * @brief  自由度，包含点和全局编号
 */
template <unsigned int DIM>
class Dofs
{
public:
    int globalIndex;
    Point<DIM> pnt;
public:
    /**
     * @brief 默认构造函数
     */
    Dofs() = default;

    /**
     * @brief 含参构造函数
     *
     * @param _pnt:存储各个维度下标的vector,左值引用
     * @param _global_index: 全局编号
     *
     */
    Dofs(const Point<DIM>& _pnt, int global_index = 0):pnt{_pnt}, globalIndex{global_index}{};
    /**
     * @brief 含参构造函数
     *
     * @param pnt:存储各个维度下标的vector，右值引用。
     * @param global_index:全局编号。
     *
     * @return
     */
    Dofs(Point<DIM>&& _pnt, int global_index = 0):pnt{std::move(_pnt)}, globalIndex{global_index}{};
    /**
     * @brief 复制构造函数
     *
     * @param _dofs:自由度
     *
     */
    Dofs(const Dofs<DIM>& _dofs)
    {
    	globalIndex = _dofs.globalIndex;
    	pnt = _dofs.pnt;
    };
    /**
     *@brief 默认析构函数
     */
    ~Dofs() = default;
    /**
     * @brief 设置全局编号。
     *
     * @param i:全局编号
     */
    void setGlobalIndex(const int i)
    {
    	globalIndex = i;
    };
    /**
     * @brief 获取全局编号。
     *
     *
     * @return 全局编号。
     */
    const int& getGlobalIndex() const
    {
        return  globalIndex;
    };
    /**
     * @brief 重载[]操作符
     *
     * @param d:第d个维度
     *
     * @return 第d个维度的坐标
     */
    const double& operator[](const unsigned int d) const
    {
	return pnt[d];
    };

    /**
     * @brief 友元函数，重载<<操作符
     *
     * @param os: ostream
     * @param dof: Dofs<D>&
     *
     * @return
     */template<unsigned int D>
    friend std::ostream& operator<<(std::ostream& os, const Dofs<D>& dof);
};

template<unsigned int D>
std::ostream& operator<<(std::ostream& os, const Dofs<D>& dof){
    os << dof.globalIndex << " : ";
    os << "( ";
    for (unsigned int d = 0; d < D - 1; d++)
    {
        os << dof.pnt[d] << " , ";
    }
    os << dof.pnt[D - 1] << " )";
    return os;
}

#else
// Do Nothing
#endif
